package cn.learn.validator.exception;

import cn.learn.util.RestResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 自定义参数校验返回异常
 *
 * @author huangyezhan
 * @version 1.0
 * @date 2020年08月01日23:07
 */
@ControllerAdvice
@ResponseBody
public class MyExceptionHandler {
    private static final Logger logger = LoggerFactory.getLogger(MyExceptionHandler.class);


    /**
     * 数据校验异常
     *
     * @param exception 异常
     * @return 返回异常结果到前端
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public RestResponse validException(MethodArgumentNotValidException exception) {

        Map<String, List<String>> map = exception.getBindingResult().getFieldErrors().stream()
                .collect(Collectors.toMap(FieldError::getField,
                        //有可能会有重复的key，所以把所有的value变成List<String>
                        e -> new ArrayList<>(Arrays.asList(e.getDefaultMessage())),
                        (List<String> oldList, List<String> newList) -> {
                            oldList.addAll(newList);
                            return oldList;
                        })
                );

        logger.warn("数据校验出问题：{}", map);
        return RestResponse.failed("002", map);
    }
    /**
     * 数据校验异常
     *
     * @param exception 异常
     * @return 返回异常结果到前端
     */
    @ExceptionHandler(value = ConstraintViolationException.class)
    public RestResponse validException(ConstraintViolationException exception) {
        Map<Path, String> collect = exception.getConstraintViolations().stream()
                .collect(Collectors.toMap(ConstraintViolation::getPropertyPath, ConstraintViolation::getMessage));

        logger.info("ConstraintViolationException 数据校验异常问题：{}", collect);
        return RestResponse.failed("0021", collect);
    }

    @ExceptionHandler(value = Exception.class)
    public RestResponse exceptionHandler(Exception e) {
        System.out.println(e.getMessage());
        e.printStackTrace();
        return RestResponse.failed("0021", "");
    }


}
